//
//  Tool.m
//  ced
//
//  Created by 尤振宇 on 15/11/6.
//  Copyright © 2015年 尤振宇. All rights reserved.
//

#import "Tool.h"
#import <MobileCoreServices/MobileCoreServices.h>
#import <objc/runtime.h>
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonHMAC.h>
#import <CommonCrypto/CommonCryptor.h>

@implementation Tool

+ (void)hideTabBarViewController:(UIViewController *)viewController
{
    if (viewController.tabBarController.tabBar.hidden == YES) {
        return;
    }
    UIView *contentView;
    if ( [[viewController.tabBarController.view.subviews objectAtIndex:0] isKindOfClass:[UITabBar class]]){
        contentView = [viewController.tabBarController.view.subviews objectAtIndex:1];
    }else{
        contentView = [viewController.tabBarController.view.subviews objectAtIndex:0];
        contentView.frame = CGRectMake(contentView.bounds.origin.x,  contentView.bounds.origin.y,  contentView.bounds.size.width, contentView.bounds.size.height + viewController.tabBarController.tabBar.frame.size.height);
        viewController.tabBarController.tabBar.hidden = YES;
    }
}

//显示tabbar的方法
+ (void)showTabBarViewController:(UIViewController *)viewController
{
    if (viewController.tabBarController.tabBar.hidden == NO)
    {
        return;
    }
    UIView *contentView;
    if ([[viewController.tabBarController.view.subviews objectAtIndex:0] isKindOfClass:[UITabBar class]]){
        
        contentView = [viewController.tabBarController.view.subviews objectAtIndex:1];
    }else{
        
        contentView = [viewController.tabBarController.view.subviews objectAtIndex:0];
        contentView.frame = CGRectMake(contentView.bounds.origin.x, contentView.bounds.origin.y,  contentView.bounds.size.width, contentView.bounds.size.height - viewController.tabBarController.tabBar.frame.size.height);
        viewController.tabBarController.tabBar.hidden = NO;
    }
    
}

+(NSString *)conversionServerTime:(NSString *)timeStr dateFormat:(NSString *)dateFormat
{
    NSArray *arr=[timeStr componentsSeparatedByString:@"+"];
    NSArray *arr1=[arr[0] componentsSeparatedByString:@"("];
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:[arr1[1] longLongValue]/1000];
    NSDateFormatter *formatter=[[NSDateFormatter alloc]init];
    [formatter setDateFormat:dateFormat];
    NSString *dateStr=[formatter stringFromDate:date];
    return dateStr;
}

/**
 *  @return 时间
 */
+(NSString *)dateWithDateFormat:(NSString *)dateFormat
{
    NSDate *date=[NSDate date];
    return [Tool dateWithDateFormat:dateFormat date:date];
}

+(NSString *)dateWithDateFormat:(NSString *)dateFormat date:(NSDate *)date
{
    NSDateFormatter *dateFormatter=[[NSDateFormatter alloc]init];
    [dateFormatter setDateFormat:dateFormat];
    return  [dateFormatter stringFromDate:date];
}

+(NSString *)ApplicationWithinTimeFormat:(NSDate *)date
{
    NSDateFormatter *dateFormatter=[[NSDateFormatter alloc]init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    return  [dateFormatter stringFromDate:date];
}

+(NSDate *)ApplicationWithString:(NSString *)string
{
    return [Tool DateForString:string format:@"yyyy-MM-dd HH:mm:ss"];
}

+(NSDate *)DateForString:(NSString *)string format:(NSString *)format
{
    NSDateFormatter *form = [[NSDateFormatter alloc]init];
    [form setDateFormat:format];
    return [form dateFromString:string];
}

+(NSString *)getDateDisplayStringByRongLian:(long long) miliSeconds{
    
    NSTimeInterval tempMilli = miliSeconds;
    NSTimeInterval seconds = tempMilli/1000.0;
    NSDate *myDate = [NSDate dateWithTimeIntervalSince1970:seconds];
    
    return [Tool getDateDisplayStringByDate:myDate];
}

+(NSString *)getDateDisplayStringByServer:(NSString *)timeStr{
    
    NSDateFormatter *format = [[NSDateFormatter  alloc] init];
    [format setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
    NSDate *myDate = [format dateFromString:timeStr];
    NSString *resultStr =[Tool getDateDisplayStringByDate:myDate];
    if ([resultStr length]>0) {
        return resultStr;
    }else{
        return timeStr;
    }
}

+(NSString *)getDateDisplayStringByDate:(NSDate *)serverDate
{
    
//    NSDateFormatter *format = [[NSDateFormatter  alloc] init];
//    [format setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
//    NSDate *myDate = [format dateFromString:timeStr];
    NSCalendar *calendar = [ NSCalendar currentCalendar ];
    int unit = NSCalendarUnitDay | NSCalendarUnitMonth |  NSCalendarUnitYear ;
    NSDateComponents *nowCmps = [calendar components:unit fromDate:[ NSDate date ]];
    NSDateComponents *myCmps = [calendar components:unit fromDate:serverDate];
    
    NSDateFormatter *dateFmt = [[ NSDateFormatter alloc ] init ];
    dateFmt.dateFormat = @"MM-dd HH:mm";
    if (nowCmps.year != myCmps.year) {
        dateFmt.dateFormat = @"yyyy-MM-dd HH:mm";
    } else {
        if (nowCmps.month == myCmps.month) {
            if (nowCmps.day==myCmps.day) {
                dateFmt.dateFormat = @"今天 HH:mm";
            }else if ((nowCmps.day-myCmps.day)==1) {
                dateFmt.dateFormat = @"昨天 HH:mm";
            }
        } 
    }
    return [dateFmt stringFromDate:serverDate];
}



+(NSString *)firstNameByChineName:(NSString *)name
{
    //转化可变的字符串
    NSMutableString *string=[NSMutableString stringWithString:name];
    //转成带音调的字符串
    CFStringTransform((CFMutableStringRef)string, NULL, kCFStringTransformMandarinLatin, NO);
    //转成字母字符串
    CFStringTransform((CFMutableStringRef)string, NULL, kCFStringTransformStripDiacritics, NO);
    
    //截取  去首字母
    NSString *firsrString=[string substringToIndex:1];
    //转成大写
    return [firsrString uppercaseString];
}


+(UIBarButtonItem *)BarButtonItemWithImage:(UIImage *)image target:(id)target action:(SEL)action
{
    UIButton*bt=[UIButton buttonWithType:UIButtonTypeCustom];
    [bt setImage:image forState:UIControlStateNormal];
    bt.frame=CGRectMake(0, 0, 33, 33);
    [bt addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
    return [[UIBarButtonItem alloc]initWithCustomView:bt];
}

+(UIBarButtonItem *)BarButtonItemWithTitle:(NSString *)title target:(id)target action:(SEL)action
{
    UIButton*bt=[UIButton buttonWithType:UIButtonTypeCustom];
    bt.frame=CGRectMake(0, 0, [title widthForFontSize:15 andHeight:33], 33);
    [bt setTitle:title forState:(UIControlStateNormal)];
    [bt addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
    [bt setTitleColor:[UIColor whiteColor] forState:(UIControlStateNormal)];
    bt.titleLabel.font=[UIFont systemFontOfSize:15];
    return [[UIBarButtonItem alloc]initWithCustomView:bt];
}

//以下方法是 容联demo 里方法
#define DefaultThumImageHigth 90.0f
#define DefaultPressImageHigth 960.0f
+(NSString*)saveToDocument:(UIImage*)image
{
    UIImage* fixImage = [Tool fixOrientation:image];
    
    NSDateFormatter* formater = [[NSDateFormatter alloc] init];
    [formater setDateFormat:@"yyyyMMddHHmmssSSS"];
    NSString* fileName =[NSString stringWithFormat:@"%@.jpg", [formater stringFromDate:[NSDate date]]];
    
    NSString* filePath=[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:fileName];
    
    //图片按0.5的质量压缩－》转换为NSData
    CGSize pressSize = CGSizeMake((DefaultPressImageHigth/fixImage.size.height) * fixImage.size.width, DefaultPressImageHigth);
    UIImage * pressImage = [Tool compressImage:fixImage withSize:pressSize];
    NSData *imageData = UIImageJPEGRepresentation(pressImage, 0.5);
    [imageData writeToFile:filePath atomically:YES];
    
    CGSize thumsize = CGSizeMake((DefaultThumImageHigth/fixImage.size.height) * fixImage.size.width, DefaultThumImageHigth);
    UIImage * thumImage = [Tool compressImage:fixImage withSize:thumsize];
    NSData * photo = UIImageJPEGRepresentation(thumImage, 0.5);
    NSString * thumfilePath = [NSString stringWithFormat:@"%@.jpg_thum", filePath];
    [photo writeToFile:thumfilePath atomically:YES];
    
    return filePath;
    
}

+ (UIImage *)fixOrientation:(UIImage *)aImage {
    // No-op if the orientation is already correct
    if (aImage.imageOrientation == UIImageOrientationUp)
        return aImage;
    // We need to calculate the proper transformation to make the image upright.
    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
    CGAffineTransform transform = CGAffineTransformIdentity;
    switch (aImage.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        default:
            break;
    }
    
    switch (aImage.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        default:
            break;
    }
    
    // Now we draw the underlying CGImage into a new context, applying the transform     // calculated above.
    CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,CGImageGetBitsPerComponent(aImage.CGImage), 0,CGImageGetColorSpace(aImage.CGImage),CGImageGetBitmapInfo(aImage.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (aImage.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
            break;
        default:              CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);              break;
    }       // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return img;
}

+ (UIImage *)compressImage:(UIImage *)image withSize:(CGSize)viewsize
{
    CGFloat imgHWScale = image.size.height/image.size.width;
    CGFloat viewHWScale = viewsize.height/viewsize.width;
    CGRect rect = CGRectZero;
    if (imgHWScale>viewHWScale)
    {
        rect.size.height = viewsize.width*imgHWScale;
        rect.size.width = viewsize.width;
        rect.origin.x = 0.0f;
        rect.origin.y =  (viewsize.height - rect.size.height)*0.5f;
    }
    else
    {
        CGFloat imgWHScale = image.size.width/image.size.height;
        rect.size.width = viewsize.height*imgWHScale;
        rect.size.height = viewsize.height;
        rect.origin.y = 0.0f;
        rect.origin.x = (viewsize.width - rect.size.width)*0.5f;
    }
    
    UIGraphicsBeginImageContext(viewsize);
    [image drawInRect:rect];
    UIImage *newimg = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return newimg;
}

+ (NSDate *)lastMonth:(NSDate *)date ;
{
    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    dateComponents.month = -1;
    return [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:date options:0];
}


+ (NSDate *)nextMonth:(NSDate *)date ;
{
    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    dateComponents.month = 1;
    return [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:date options:0];
}

+ (NSDate *)lastYear:(NSDate *)date ;
{
    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    dateComponents.year = -1;
    return [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:date options:0];
}

+ (NSDate *)tomorrow:(NSDate *)date
{
    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    dateComponents.day = 1;
    return [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:date options:0];
}


+ (NSDate *)yesterday:(NSDate *)date
{
    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    dateComponents.day = -1;
    return [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:date options:0];
}

+(NSDate *)year:(NSString *)year month:(NSString *)month day:(NSString *)day
{
    
    NSString *dateStr=[NSString stringWithFormat:@"%@-%@-%@",year,month,day];
    
    NSDateFormatter *formatter=[[NSDateFormatter alloc]init];
    [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    NSDate *date=[formatter dateFromString:dateStr];
    return date;
}

//不适配iOS11
//+(void)setNavigationBackImage:(UIImage *)image needText:(BOOL)needText
//{
//    [[UIBarButtonItem appearance] setBackButtonBackgroundImage:image forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
//    if (!needText) {
//        [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(NSIntegerMin, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];
//    }
//}
//+(NSString*)getExpressionStrById:(NSInteger)idx
//{
//    NSString * str = [self getExpressionById:idx];
//    if (emojiConvert == nil)
//    {
//        emojiConvert = [EmojiConvertor sharedInstance];
//    }
//    return [emojiConvert convertEmojiSoftbankToUnicode:str];
//}
//+(NSString*)getExpressionById:(NSInteger)idx
//{
//    switch(idx)
//    {
//        case 0: return @"\ue415";
//        case 1: return @"\ue056";
//        case 2: return @"\ue057";
//        case 3: return @"\ue414";
//        case 4: return @"\ue405";
//        case 5: return @"\ue106";
//        case 6: return @"\ue418";
//        case 7: return @"\ue417";
//        case 8: return @"\ue40d";
//        case 9: return @"\ue40a";
//        case 10: return @"\ue404";
//        case 11: return @"\ue105";
//        case 12: return @"\ue409";
//        case 13: return @"\ue40e";
//        case 14: return @"\ue402";
//        case 15: return @"\ue108";
//        case 16: return @"\ue403";
//        case 17: return @"\ue058";
//        case 18: return @"\ue407";
//        case 19: return @"\ue401";
//        case 20: return @"\ue40f";
//        case 21: return @"\ue40b";
//        case 22: return @"\ue406";
//        case 23: return @"\ue413";
//        case 24: return @"\ue411";
//        case 25: return @"\ue412";
//        case 26: return @"\ue410";
//        case 27: return @"\ue107";
//        case 28: return @"\ue059";
//        case 29: return @"\ue416";
//        case 30: return @"\ue408";
//        case 31: return @"\ue40c";
//        case 32: return @"\ue11a";
//        case 33: return @"\ue10c";
//        case 34: return @"\ue022";
//        case 35: return @"\ue023";
//        case 36: return @"\ue329";
//        case 37: return @"\ue32e";
//        case 38: return @"\ue335";
//        case 39: return @"\ue337";
//        case 40: return @"\ue336";
//        case 41: return @"\ue13c";
//        case 42: return @"\ue331";
//        case 43: return @"\ue03e";
//        case 44: return @"\ue11d";
//        case 45: return @"\ue05a";
//        case 46: return @"\ue00e";
//        case 47: return @"\ue421";
//        case 48: return @"\ue420";
//        case 49: return @"\ue00d";
//        case 51: return @"\ue011";
//        case 52: return @"\ue22e";
//        case 53: return @"\ue22f";
//        case 54: return @"\ue231";
//        case 55: return @"\ue230";
//        case 56: return @"\ue00f";
//        case 57: return @"\ue14c";
//        case 58: return @"\ue111";
//        case 59: return @"\ue425";
//        case 60: return @"\ue001";
//        case 61: return @"\ue002";
//        case 62: return @"\ue005";
//        case 63: return @"\ue004";
//        case 64: return @"\ue04e";
//        case 65: return @"\ue11c";
//        case 66: return @"\ue003";
//        case 67: return @"\ue04a";
//        case 68: return @"\ue04b";
//        case 69: return @"\ue049";
//        case 70: return @"\ue048";
//        case 71: return @"\ue04c";
//        case 72: return @"\ue13d";
//        case 73: return @"\ue43e";
//        case 74: return @"\ue04f";
//        case 75: return @"\ue052";
//        case 76: return @"\ue053";
//        case 77: return @"\ue524";
//        case 78: return @"\ue52c";
//        case 79: return @"\ue52a";
//        case 80: return @"\ue531";
//        case 81: return @"\ue050";
//        case 82: return @"\ue527";
//        case 83: return @"\ue051";
//        case 84: return @"\ue10b";
//        case 85: return @"\ue52b";
//        case 86: return @"\ue52f";
//        case 87: return @"\ue109";
//        case 88: return @"\ue528";
//        case 89: return @"\ue01a";
//        case 90: return @"\ue52d";
//        case 91: return @"\ue521";
//        case 92: return @"\ue52e";
//        case 93: return @"\ue055";
//        case 94: return @"\ue525";
//        case 95: return @"\ue10a";
//        case 96: return @"\ue522";
//        case 97: return @"\ue054";
//        case 98: return @"\ue520";
//        case 99: return @"\ue032";
//        case 100: return @"\ue303";
//        case 101: return @"\ue307";
//        case 102: return @"\ue308";
//        case 103: return @"\ue437";
//        case 104: return @"\ue445";
//        case 105: return @"\ue11b";
//        case 106: return @"\ue448";
//        case 107: return @"\ue033";
//        case 108: return @"\ue112";
//        case 109: return @"\ue325";
//        case 110: return @"\ue312";
//        case 111: return @"\ue310";
//        case 112: return @"\ue126";
//        case 113: return @"\ue008";
//        case 114: return @"\ue03d";
//        case 115: return @"\ue00c";
//        case 116: return @"\ue12a";
//        case 117: return @"\ue009";
//        case 118: return @"\ue145";
//        case 119: return @"\ue144";
//        case 120: return @"\ue03f";
//        case 121: return @"\ue116";
//        case 122: return @"\ue10f";
//        case 123: return @"\ue101";
//        case 124: return @"\ue13f";
//        case 125: return @"\ue12f";
//        case 126: return @"\ue311";
//        case 127: return @"\ue113";
//        case 128: return @"\ue30f";
//        case 129: return @"\ue42b";
//        case 130: return @"\ue42a";
//        case 131: return @"\ue018";
//        case 132: return @"\ue016";
//        case 133: return @"\ue015";
//        case 134: return @"\ue131";
//        case 135: return @"\ue12b";
//        case 136: return @"\ue03c";
//        case 137: return @"\ue041";
//        case 138: return @"\ue322";
//        case 139: return @"\ue10e";
//        case 140: return @"\ue43c";
//        case 141: return @"\ue323";
//        case 142: return @"\ue31c";
//        case 143: return @"\ue034";
//        case 144: return @"\ue035";
//        case 145: return @"\ue045";
//        case 146: return @"\ue047";
//        case 147: return @"\ue30c";
//        case 148: return @"\ue044";
//        case 149: return @"\ue120";
//        case 150: return @"\ue33b";
//        case 151: return @"\ue33f";
//        case 152: return @"\ue344";
//        case 153: return @"\ue340";
//        case 154: return @"\ue147";
//        case 155: return @"\ue33a";
//        case 156: return @"\ue34b";
//        case 157: return @"\ue345";
//        case 158: return @"\ue01d";
//        case 159: return @"\ue10d";
//        case 160: return @"\ue136";
//        case 161: return @"\ue435";
//        case 162: return @"\ue252";
//        case 163: return @"\ue132";
//        case 164: return @"\ue138";
//        case 165: return @"\ue139";
//        case 166: return @"\ue332";
//        case 167: return @"\ue333";
//        case 168: return @"\ue24e";
//        case 169: return @"\ue24f";
//        case 170: return @"\ue537";
//    }
//    return @"\ue056";
//}

//+(UIView *)LookOthersWithText:(NSString *)text target:(id)target action:(SEL)action
//{
//    UIView *view=[[UIView alloc]initWithFrame:CGRectMake(0, 0, JCWIDTH, 35)];
//    view.backgroundColor=[UIColor groupTableViewBackgroundColor];
//    view.userInteractionEnabled=YES;
//    
//    UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(0, 0, view.width, view.height)];
//    label.text=[NSString stringWithFormat:@"     查看其它人%@",text];
//    label.userInteractionEnabled=YES;
//    label.font=kFont_Big;
//    [view addSubview:label];
//    
//    UIImageView *image=[[UIImageView alloc]initWithFrame:CGRectMake(JCWIDTH-20, 0, 7, 11)];
//    image.centerY=view.height/2;
//    image.image=[UIImage imageNamed:@"go"];
//    [view addSubview:image];
//    
//    UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc]initWithTarget:target action:action];
//    [label addGestureRecognizer:tap];
//    return view;
//}

+(NSString *)EmailBodyDeleteRedundantHTML:(NSString *)string
{
    NSRange range=[string rangeOfString:@"<html"];
    NSRange range1=[string rangeOfString:@"</html>"];
    
    NSString *newHTML;
    if (range.length > 0 && range1.length>0) {
        newHTML=[string substringWithRange:NSMakeRange(range.location, range1.location+range1.length-range.location)];
        
    }
    
    NSMutableString * html = [NSMutableString string];
    [html appendFormat:@"<html><head><script>%@</script></head>"
     @"<body>%@</body><iframe src='x-mailcore-msgviewloaded:' style='width: 0px; height: 0px; border: none;'>"
     @"</iframe></html>", [Tool mainJavaScript], newHTML?newHTML:string];
    return html;
}

+(NSString *)mainJavaScript;
{
    return @"\
    var imageElements = function() {\
    var imageNodes = document.getElementsByTagName('img');\
    return [].slice.call(imageNodes);\
    };\
    \
    var findCIDImageURL = function() {\
    var images = imageElements();\
    \
    var imgLinks = [];\
    for (var i = 0; i < images.length; i++) {\
    var url = images[i].getAttribute('src');\
    if (url.indexOf('cid:') == 0)\
    imgLinks.push(url);\
    }\
    return JSON.stringify(imgLinks);\
    };\
    \
    var replaceImageSrc = function(info) {\
    var images = imageElements();\
    \
    for (var i = 0; i < images.length; i++) {\
    var url = images[i].getAttribute('src');\
    if (url.indexOf(info.URLKey) == 0) {\
    images[i].setAttribute('src', info.LocalPathKey);\
    break;\
    }\
    }\
    };\
    ";
}


+(BOOL)validateEmail:(NSString *)email
{
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailTest evaluateWithObject:email];
}

//调用C语言的API来获得文件的MIMEType ，只能获取本地文件哦，无法获取网络请求来的文件
+(NSString *)getMIMETypeWithCAPIAtFilePath:(NSString *)path
{
    if (![[[NSFileManager alloc] init] fileExistsAtPath:path]) {
        return nil;
    }
    
    CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[path pathExtension], NULL);
    CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType);
    CFRelease(UTI);
    if (!MIMEType) {
        return @"application/octet-stream";
    }
    return (__bridge NSString *)(MIMEType);
}

+(BOOL)validateMobile:(NSString *)mobile
{
    NSString *phoneRegex = @"^([0-9]{3,4}-)?[0-9]{7,8}$|([0-9]{3,4})?[0-9]{7,8}$|[1][3-8]\\d{9}$";
    NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",phoneRegex];
    return [phoneTest evaluateWithObject:mobile];
}

+(void)hideScarchBarClearButton:(UISearchBar *)searchBar
{
    for (UIView *view in searchBar.subviews[0].subviews) {
        if ([view isKindOfClass:[UITextField class]]) {
            UITextField *searchField = (UITextField *)view;
            searchField.clearButtonMode = UITextFieldViewModeNever;
        }
    }
}

+(void)folderSizeAtPath:(NSString *)folderPath operation:(void(^)(float folderSize))operation
{
    dispatch_queue_t systemQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_async(systemQueue, ^{
        
        NSFileManager* manager = [NSFileManager defaultManager];
        
        if (![manager fileExistsAtPath:folderPath]) {
            
            return ;
        }
        
        NSEnumerator *childFilesEnumerator = [[manager subpathsAtPath:folderPath] objectEnumerator];
        
        NSString* fileName;
        
        long long folderSize = 0;
        
        while ((fileName = [childFilesEnumerator nextObject]) != nil){
            NSString* fileAbsolutePath = [folderPath stringByAppendingPathComponent:fileName];
            folderSize += [self fileSizeAtPath:fileAbsolutePath];
        }
        
        dispatch_sync(dispatch_get_main_queue(), ^{
            operation(folderSize/(1024.0*1024.0));
        });
    });
}

+(long long)fileSizeAtPath:(NSString *)filePath
{
    NSFileManager* manager = [NSFileManager defaultManager];
    if ([manager fileExistsAtPath:filePath]){
        return [[manager attributesOfItemAtPath:filePath error:nil] fileSize];
    }
    return 0;
}

+(void)clearFolder:(NSString *)path mainThread:(dispatch_block_t)block
{
    NSFileManager* manager = [NSFileManager defaultManager];
    
    if (![manager fileExistsAtPath:path]) return;
    NSArray *subPaths = [manager subpathsAtPath:path];
    dispatch_queue_t systemQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_async(systemQueue, ^{
        for (NSString *subPath in subPaths) {
            [manager removeItemAtPath:[path stringByAppendingPathComponent:subPath] error:nil];
        }
        dispatch_sync(dispatch_get_main_queue(), block);
    });
}

+(NSString *)fileSize:(float)size
{
    return size >= 1 ? [NSString stringWithFormat:@"%.2f M",size] : [NSString stringWithFormat:@"%.2f K",size * 1024];
}

@end


@implementation NSDate (Category)

-(NSDate *)currentTimeZone
{
    NSTimeZone *zone = [NSTimeZone systemTimeZone];
    NSInteger interval = [zone secondsFromGMTForDate:self];
    return [self dateByAddingTimeInterval:interval];
}

-(BOOL)todayLater:(BOOL)onlyAfter
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
    
    NSDate *date = [NSDate dateWithTimeIntervalSinceNow:28800];
    NSDateComponents *cmps = [calendar components:unit fromDate:date toDate:self options:0];
    
    if (onlyAfter) {
        
        if ([calendar isDateInToday:self]) {
            return NO;
        }else if (cmps.year >= 0 && cmps.month >= 0 && cmps.day >= 0){
            return YES;
        }else{
            return NO;
        }
    }else{
        
        if (cmps.year >= 0 && cmps.month >= 0 && cmps.day >= 0){
            return YES;
        }else{
            return NO;
        }
    }
}

@end

@implementation NSDictionary (Category)
-(NSString * )JSONStr
{
    NSData *data = [NSJSONSerialization dataWithJSONObject:self options:NSJSONWritingPrettyPrinted error:nil];
    NSString *JSON = [[NSString alloc]initWithData:data encoding:(NSUTF8StringEncoding)];
    return JSON;
}
@end

@implementation NSString (Category)
-(NSDictionary * )JSONDictionary
{
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    return [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
}

-(NSString *)UTF8Value
{
   NSString *encodedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes( kCFAllocatorDefault, (CFStringRef)self, NULL, NULL,  kCFStringEncodingUTF8));
    return encodedString;
}

-(CLLocationCoordinate2D)CLLocationCoordinate2DValue
{
    NSArray *arr = [self componentsSeparatedByString:@","];
    CLLocationCoordinate2D coor;
    coor.longitude = [arr[0] doubleValue];
    coor.latitude = [arr[1] doubleValue];
    return coor;
}

-(float)widthForFontSize:(float)fontSize andHeight:(float)height
{
    NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:(fontSize)]};
    CGRect rect =[self boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, height) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
    return rect.size.width;
}

-(float)heightForFontSize:(float)fontSize andWidth:(float)width
{
    NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:(fontSize)]};
    CGRect rect =[self boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
    return rect.size.height;
}

-(NSString *)SHA1Coding
{
    const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:self.length];
    uint8_t digest[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(data.bytes, (int)data.length, digest);
    NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
    for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
        [output appendFormat:@"%02x", digest[i]];
    return output;
}

-(NSString *)BASE64Coding
{
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    return [data base64EncodedStringWithOptions:0];
}

-(NSString *)BASE64Decoding
{
    NSData *data = [[NSData alloc]initWithBase64EncodedString:self options:0];
    return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
}

-(NSString *)HMAC_SHA1Coding:(NSString *)key
{
    const char *cKey  = [key cStringUsingEncoding:NSASCIIStringEncoding];
    const char *cData = [self cStringUsingEncoding:NSASCIIStringEncoding];
    unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];
    CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
    NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC
                                          length:sizeof(cHMAC)];
    NSString *hash = [HMAC base64EncodedStringWithOptions:0];
    return hash;
}

-(UIColor *)colorWithHexString
{
    NSString *cString = [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
    
    // String should be 6 or 8 characters
    if ([cString length] < 6) {
        return [UIColor clearColor];
    }
    // 判断前缀
    if ([cString hasPrefix:@"0X"])
        cString = [cString substringFromIndex:2];
    if ([cString hasPrefix:@"#"])
        cString = [cString substringFromIndex:1];
    if ([cString length] != 6)
        return [UIColor clearColor];
    // 从六位数值中找到RGB对应的位数并转换
    NSRange range;
    range.location = 0;
    range.length = 2;
    //R、G、B
    NSString *rString = [cString substringWithRange:range];
    range.location = 2;
    NSString *gString = [cString substringWithRange:range];
    range.location = 4;
    NSString *bString = [cString substringWithRange:range];
    // Scan values
    unsigned int r, g, b;
    [[NSScanner scannerWithString:rString] scanHexInt:&r];
    [[NSScanner scannerWithString:gString] scanHexInt:&g];
    [[NSScanner scannerWithString:bString] scanHexInt:&b];
    
    return [UIColor colorWithRed:((float) r / 255.0f) green:((float) g / 255.0f) blue:((float) b / 255.0f) alpha:1.0f];
}

-(BOOL)validateEmail
{
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailTest evaluateWithObject:self];
}
-(BOOL)validateMobile
{
    NSString *phoneRegex = @"^([0-9]{3,4}-)?[0-9]{7,8}$|([0-9]{3,4})?[0-9]{7,8}$|[1][3-8]\\d{9}$";
    NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",phoneRegex];
    return [phoneTest evaluateWithObject:self];
}

@end

@implementation NSObject (Category)

-(NSDictionary *)AllAttributesAndTheAttributeValues
{
    NSMutableDictionary *props = [NSMutableDictionary dictionary];
    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList([self class], &outCount);
    for (i = 0; i<outCount; i++)
    {
        objc_property_t property = properties[i];
        const char* char_f =property_getName(property);
        NSString *propertyName = [NSString stringWithUTF8String:char_f];
        id propertyValue = [self valueForKey:(NSString *)propertyName];
        if (propertyValue) [props setObject:propertyValue forKey:propertyName];
    }
    free(properties);
    return props;
}

- (NSArray *)AllAttributes
{
    u_int count;
    objc_property_t *properties  =class_copyPropertyList([self class], &count);
    NSMutableArray *propertiesArray = [NSMutableArray arrayWithCapacity:count];
    
    for (int i = 0; i<count; i++){
        const char* propertyName =property_getName(properties[i]);
        [propertiesArray addObject: [NSString stringWithUTF8String: propertyName]];
    }
    free(properties);
    return propertiesArray;
}


@end

@implementation NSFileManager (Category)
- (NSArray *)folderAllFileAtPath:(NSString *)folderPath
{
    if (![self fileExistsAtPath:folderPath]) return nil;
    NSEnumerator *childFilesEnumerator = [[self subpathsAtPath:folderPath] objectEnumerator];
    
    NSString *fileName;
    NSMutableArray *paths = [NSMutableArray array];
    while ((fileName = [childFilesEnumerator nextObject]) != nil){
        
        NSString *fileAbsolutePath = [folderPath stringByAppendingPathComponent:fileName];
        [paths addObject:fileAbsolutePath];
        
    }
    return paths;
}
@end

@implementation AppDelegate (Category)

+(instancetype)sharedApplication
{
    return (AppDelegate *)[[UIApplication sharedApplication] delegate];
}

@end

@implementation NSBundle (Category)

+(NSString *)BundleIdentifier
{
    return [[[self mainBundle]infoDictionary] objectForKey:@"CFBundleIdentifier"];
}

+(NSString *)APPName
{
    return [[[self mainBundle]infoDictionary] objectForKey:@"CFBundleDisplayName"];
}

+(float)iOS_Version
{
    return [[[[self mainBundle]infoDictionary] objectForKey:@"DTPlatformVersion"]floatValue];
}
@end

@implementation UIView (Category)

+(id)ViewWithXib
{
    return [[[NSBundle mainBundle]loadNibNamed:NSStringFromClass(self) owner:nil options:nil]firstObject];
}

-(void)roundedCorners_5PX
{
    [self roundedCorners:5];
}

-(void)roundedCorners_10PX
{
    [self roundedCorners:10];
}

-(void)roundedCorners:(CGFloat)corners
{
    self.layer.cornerRadius = corners;
    self.layer.masksToBounds = YES;
}

-(void)borderWidthAndColor:(UIColor *)color
{
    self.layer.borderColor = color.CGColor;
    self.layer.borderWidth = 1;
}
@end

@implementation UIImage (Category)

-(UIImage *)adjustToSize:(CGSize)newSize
{
    CGFloat imgHWScale = self.size.height/self.size.width;
    CGFloat viewHWScale = newSize.height/newSize.width;
    CGRect rect = CGRectZero;
    if (imgHWScale>viewHWScale)
    {
        rect.size.height = newSize.width*imgHWScale;
        rect.size.width = newSize.width;
        rect.origin.x = 0.0f;
        rect.origin.y =  (newSize.height - rect.size.height)*0.5f;
    }
    else
    {
        CGFloat imgWHScale = self.size.width/self.size.height;
        rect.size.width = newSize.height*imgWHScale;
        rect.size.height = newSize.height;
        rect.origin.y = 0.0f;
        rect.origin.x = (newSize.width - rect.size.width)*0.5f;
    }
    
    UIGraphicsBeginImageContext(newSize);
    [self drawInRect:rect];
    UIImage *newimg = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return newimg;
}

-(UIImage *)imageCompressForWidth:(CGFloat)defineWidth
{
    UIImage *newImage = nil;
    CGSize imageSize = self.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;
    CGFloat targetWidth = defineWidth;
    CGFloat targetHeight = height / (width / targetWidth);
    CGSize size = CGSizeMake(targetWidth, targetHeight);
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;
    CGPoint thumbnailPoint = CGPointMake(0.0, 0.0);
    if(CGSizeEqualToSize(imageSize, size) == NO){
        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;
        if(widthFactor > heightFactor){
            scaleFactor = widthFactor;
        }        else{
            scaleFactor = heightFactor;
        }
        scaledWidth = width * scaleFactor;
        scaledHeight = height * scaleFactor;
        if(widthFactor > heightFactor){
            thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
        }else if(widthFactor < heightFactor){
            thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
        }
    }
    UIGraphicsBeginImageContext(size);
    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width = scaledWidth;
    thumbnailRect.size.height = scaledHeight;
    
    [self drawInRect:thumbnailRect];
    
    newImage = UIGraphicsGetImageFromCurrentImageContext();
    if(newImage == nil){
        NSLog(@"scale image fail");
    }
    
    UIGraphicsEndImageContext();
    return newImage;
}

+ (UIImage *) resizeCodeImage:(CIImage *)image withSize:(CGSize)size
{
    if (image) {
        CGRect extent = CGRectIntegral(image.extent);
        CGFloat scaleWidth = size.width/CGRectGetWidth(extent);
        CGFloat scaleHeight = size.height/CGRectGetHeight(extent);
        size_t width = CGRectGetWidth(extent) * scaleWidth;
        size_t height = CGRectGetHeight(extent) * scaleHeight;
        CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceGray();
        CGContextRef contentRef = CGBitmapContextCreate(nil, width, height, 8, 0, colorSpaceRef, (CGBitmapInfo)kCGImageAlphaNone);
        CIContext *context = [CIContext contextWithOptions:nil];
        CGImageRef imageRef = [context createCGImage:image fromRect:extent];
        CGContextSetInterpolationQuality(contentRef, kCGInterpolationNone);
        CGContextScaleCTM(contentRef, scaleWidth, scaleHeight);
        CGContextDrawImage(contentRef, extent, imageRef);
        CGImageRef imageRefResized = CGBitmapContextCreateImage(contentRef);
        CGContextRelease(contentRef);
        CGImageRelease(imageRef);
        return [UIImage imageWithCGImage:imageRefResized];
    }else{
        return nil;
    }
}

@end


@implementation CALayer (Category)

+(void)cancelAnimation:(void(^)())block
{
    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    if (block) {
        block();
    }
    [CATransaction commit];
}

@end


